// 重构了部分，原来的代码改不大动，而且功能有缺失 by songyf
import {
  ElConfigProvider,
  ElDatePicker,
  ElTimePicker,
  ElTimeSelect,
} from 'element-plus';
import arrowDownIcon from './assets/t-arrow-down.svg';
// import arrowLeftIcon from './assets/t-arrow-left.svg';
// import arrowRightIcon from './assets/t-arrow-right.svg';
import { en, zhCn, zhTw, pt, ru, kk } from 'element-plus/es/locales.mjs';
import { useFormChild, useQuasar } from '@teld/q-components';
import Icon from '@teld/q-components/Icon';
import TmDateTimePicker from '@teld/tm-components/DateTimePicker';
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import isBetween from 'dayjs/plugin/isBetween';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
  commonProps,
  fixNameSpace,
  pickOwnForBasicComponent,
} from 't/common/utils';
import {
  computed,
  defineComponent,
  nextTick,
  onMounted,
  ref,
  watch,
} from 'vue';
import Button from '../button';
import Input from '../input';
import LabelPrefixWraper from '../label-prefix-wraper';
import styles from './index.module.scss';
import './index.scss';

export default defineComponent({
  name: 'TDateTime',
  props: {
    ...commonProps,
    ...Input.props,
    ...LabelPrefixWraper.props,
    elDatePickerOptions: {
      type: Object,
      default() {
        return {};
      },
    },
    elTimePickerOptions: {
      type: Object,
      default() {
        return {};
      },
    },
    elTimeSelectOptions: {
      type: Object,
      default() {
        return {};
      },
    },
    tmRef: {
      type: Object,
      default() {
        return {};
      },
    },
    format: {
      type: String,
      default() {
        return null;
      },
    },
    valueFormat: {
      type: String,
      default() {
        return null;
      },
    },
    displayFormatWithDate: {
      type: String,
      default() {
        return 'YYYY/MM/DD';
      },
    },
    displayFormatWithDateTime: {
      type: String,
      default() {
        return 'YYYY/MM/DD HH:mm:ss';
      },
    },
    displayFormatWithTime: {
      type: String,
      default() {
        return 'HH:mm:ss';
      },
    },
    dateType: {
      type: String,
      default() {
        return 'datetime';
      },
    },
    minDate: {
      type: String,
      default() {
        return '';
      },
    },
    maxDate: {
      type: String,
      default() {
        return '';
      },
    },
    start: {
      type: String,
      default() {
        return '09:00';
      },
    },
    end: {
      type: String,
      default() {
        return '18:00';
      },
    },
    step: {
      type: String,
      default() {
        return '00:30';
      },
    },
    rules: {
      type: Array,
      default() {
        return undefined;
      },
    },
    dateWithTime: {
      type: Boolean,
      default() {
        return false;
      },
    },
    defaultTimeForDateTime: {
      type: String,
      default() {
        return '0';
      },
    },
    dateColumnsType: {
      type: Array,
      default() {
        return ['year', 'month', 'day'];
      },
    },
    timeColumnsType: {
      type: Array,
      default() {
        return ['hour', 'minute', 'second'];
      },
    },
  },
  emits: [
    'update:modelValue',
    'change',
    'blur',
    'focus',
    'clear',
    'calendarChange',
    'visibleChange',
  ],

  setup(props, { attrs, emit, expose, slots }) {
    const $q = useQuasar();
    const refInput = ref();
    const refDate = ref();
    const refTime = ref();
    const refTimeSelect = ref();
    const refPicker = ref();
    const dateTime = ref('');

    const inputDateTime = ref('');
    const tmDateTime = ref('');
    const mobileScreen = computed(() => {
      return $q.screen.xs || $q.platform.is.mobile;
    });
    dayjs.extend(customParseFormat);
    dayjs.extend(isBetween);
    dayjs.extend(isSameOrAfter);
    dayjs.extend(isSameOrBefore);
    const defaultTimeMap = {
      0: new Date(2000, 1, 1, 0, 0, 0),
      12: new Date(2000, 1, 1, 12, 0, 0),
      24: new Date(2000, 1, 1, 23, 59, 59),
      now: new Date(),
    };
    const [mappingProps, mappingExpose] = useMappingProps(props, {
      validate() {
        if (mobileScreen.value) {
          return refInput.value.validate(...arguments);
        } else {
          return divValidata();
        }
      },
      resetValidation() {
        if (mobileScreen.value) {
          refInput.value.resetValidation(...arguments);
        } else {
          validataResult.value = true;
        }
      },
      value: { dateValue: dateTime, inputValue: inputDateTime },
      focus() {
        if (mobileScreen.value) {
          refInput.value.focus(...arguments);
        } else {
          if (mappingProps.dateType === 'time') {
            refTime.value.focus();
          }
          if (
            mappingProps.dateType === 'date' ||
            mappingProps.dateType === 'datetimerange' ||
            mappingProps.dateType === 'datetime'
          ) {
            refDate.value.focus();
          }
        }
      },
      blur() {
        if (mobileScreen.value) {
          refInput.value.blur(...arguments);
        } else {
          if (mappingProps.dateType === 'time') {
            refTime.value.blur();
          }
          if (
            mappingProps.dateType === 'date' ||
            mappingProps.dateType === 'datetimerange' ||
            mappingProps.dateType === 'daterange' ||
            mappingProps.dateType === 'datetime'
          ) {
            refDate.value.blur();
          }
        }
      },
      handleOpen() {
        if (mappingProps.dateType === 'time') {
          refTime.value.handleOpen();
        }
        if (
          mappingProps.dateType === 'date' ||
          mappingProps.dateType === 'datetimerange' ||
          mappingProps.dateType === 'daterange' ||
          mappingProps.dateType === 'datetime'
        ) {
          refDate.value.handleOpen();
        }
      },
      handleClose() {
        if (mappingProps.dateType === 'time') {
          refTime.value.handleClose();
        }
        if (
          mappingProps.dateType === 'date' ||
          mappingProps.dateType === 'datetimerange' ||
          mappingProps.dateType === 'daterange' ||
          mappingProps.dateType === 'datetime'
        ) {
          refDate.value.handleClose();
        }
      },
    });

    //与form校验绑定
    useFormChild({
      validate: function () {
        if (mobileScreen.value) {
          return refInput.value.validate(...arguments);
        } else {
          return divValidata();
        }
      }, // 函数；可以是异步的；
      // 应该返回一个布尔值（或一个 resolve 布尔值的 Promise）
      resetValidation: function () {
        if (mobileScreen.value) {
          refInput.value.resetValidation(...arguments);
        } else {
          validataResult.value = true;
        }
      }, // 可选的函数，可重置验证
      requiresQForm: false, // 如果没有找到父级 QForm，它是否应该报错？
    });
    expose({ ...mappingExpose, showPopup });
    //设置默认值
    if (mappingProps.disable || mappingProps.readonly) {
      mappingProps.placeholder = '';
    }
    mappingProps.borderType = 'borderless';
    //手动控制弹窗显隐
    function showPopup() {
      if (mobileScreen.value) {
        showTmPicker();
      } else {
        refDate.value.handleOpen();
      }
    }

    //设置格式
    const formatMap = {
      date: mappingProps.displayFormatWithDate,
      time: mappingProps.displayFormatWithTime,
      datetime: mappingProps.displayFormatWithDateTime,
      datetimerange: mappingProps.displayFormatWithDateTime,
      daterange: mappingProps.displayFormatWithDate,
      timeselect: 'HH:mm',
    };
    let dateTimeFormat = formatMap[mappingProps.dateType];
    if (
      mappingProps.displayFormatWithDate == 'YYYY/MM' &&
      mappingProps.dateType == 'date'
    ) {
      mappingProps.dateColumnsType = ['year', 'month'];
    }
    if (
      mappingProps.displayFormatWithTime == 'HH:mm' &&
      mappingProps.dateType == 'time'
    ) {
      mappingProps.timeColumnsType = ['hour', 'minute'];
    }
    watch(
      () => {
        return mappingProps.dateType;
      },
      (newVal, oldVal) => {
        if (newVal != oldVal) {
          dateTimeFormat = formatMap[mappingProps.dateType];
          nextTick(() => {
            changeIconPosition();
          });
          initDateTime();
        }
      },
    );
    // 改变尺寸是重新对图标进行移动
    watch(
      () => {
        return mobileScreen.value;
      },
      (newVal, oldVal) => {
        if (!newVal) {
          nextTick(() => {
            changeIconPosition();
          });
        }
      },
    );
    watch(
      () => {
        return mappingProps.modelValue;
      },
      (newVal, oldVal) => {
        // if (newVal != oldVal) {
        initDateTime();
        // dateTime.value = mappingProps.modelValue;
        //赋值时主动触发校验
        if (mobileScreen.value) {
          nextTick(() => {
            refInput.value.validate();
          });
        }

        // valueUpdate(newVal);
      },
      // },
    );

    let mobileMinDate = computed(() => {
      let minDate = new Date();
      if (mappingProps.minDate) {
        minDate = new Date(
          dayjs(mappingProps.minDate).year(),
          dayjs(mappingProps.minDate).month(),
          dayjs(mappingProps.minDate).date(),
          0,
          0,
          0,
        );
      } else {
        minDate = new Date(dayjs().year() - 5, dayjs().month(), dayjs().date());
      }
      return minDate;
    });
    let mobileMaxDate = computed(() => {
      let maxDate = new Date();
      if (mappingProps.maxDate) {
        maxDate = new Date(
          dayjs(mappingProps.maxDate).year(),
          dayjs(mappingProps.maxDate).month(),
          dayjs(mappingProps.maxDate).date(),
        );
      } else {
        maxDate = new Date(
          dayjs().year() + 5,
          dayjs().month(),
          dayjs().date(),
          23,
          59,
          59,
        );
      }
      return maxDate;
    });
    // 时间格式转化Element
    const initDateTime = () => {
      // 未绑定数据源或为空
      if (!mappingProps.modelValue) {
        inputDateTime.value = '';
        dateTime.value = '';
        return;
      }
      // 范围数组或Date格式
      if (
        typeof mappingProps.modelValue === 'object' &&
        mappingProps.modelValue !== null
      ) {
        if (mappingProps.dateType.indexOf('range') > -1) {
          if (mappingProps.modelValue.length < 2) {
            dateTime.value = [];
            inputDateTime.value = '';
          } else {
            dateTime.value = [
              mappingProps.modelValue[0],
              mappingProps.modelValue[1],
            ];
            inputDateTime.value =
              mappingProps.modelValue[0] && mappingProps.modelValue[1]
                ? `${mappingProps.modelValue[0]} - ${mappingProps.modelValue[1]}`
                : '';
          }
        } else {
          dateTime.value = parseDateTime(mappingProps.modelValue);
          inputDateTime.value = parseDateTime(mappingProps.modelValue);
        }
      }
      // 字符串格式
      if (typeof mappingProps.modelValue === 'string') {
        if (mappingProps.modelValue.indexOf('@') > -1) {
          dateTime.value = mappingProps.modelValue;
          inputDateTime.value = mappingProps.modelValue;
        } else {
          dateTime.value = calDateTime(mappingProps.modelValue);
          inputDateTime.value = mappingProps.modelValue
            ? calDateTime(mappingProps.modelValue)
            : '';
        }
      }
    };
    // 多语言适配
    const language = {
      'en': en,
      'en-US': en,
      'zh-CN': zhCn,
      'zh-TW': zhTw,
      'zh-HK': zhTw,
      'zh-Hant': zhTw,
      'pt': pt,
      'pt-BR': pt,
      'ru': ru,
      'ru-RU': ru,
      'ru-KZ': ru,
      'kk': kk,
      'kk-KZ': kk,
    };

    function getUserLanguage() {
      return window.readCookie && readCookie?.('teld_locale');
    }

    onMounted(() => {
      // 手动设置tabindex
      if (refDate.value) {
        refDate.value.$el.nextElementSibling
          .querySelector('input')
          .setAttribute('tabindex', attrs.tabIndex ?? attrs.tabindex ?? 1);
      }
      if (refTime.value) {
        refTime.value.$el.nextElementSibling
          .querySelector('input')
          .setAttribute('tabindex', attrs.tabIndex ?? attrs.tabindex ?? 1);
      }
      // 更改图标位置
      changeIconPosition();
      // 时间格式化
      initDateTime();
      // 时间选择移动端兼容
      if (mappingProps.dateType == 'timeselect' && mappingProps.start) {
        const filter = (type, options, values) => {
          if (type === 'hour') {
            let start = parseInt(mappingProps.start.split(':')[0]);
            let end = parseInt(mappingProps.end.split(':')[0]);
            return options.filter(
              option =>
                Number(option.value) >= start && Number(option.value) <= end,
            );
          }
          if (type === 'minute') {
            let start = parseInt(mappingProps.start.split(':')[1]);
            let end = parseInt(mappingProps.end.split(':')[1]);
            let step =
              parseInt(mappingProps.step) > 1
                ? 60
                : parseInt(mappingProps.step.split(':')[1]);
            return options.filter(
              option =>
                Number(option.value) >= start &&
                Number(option.value) <= end &&
                Number(option.value) % step === 0,
            );
          }
          return options;
        };
        refPicker.value.timePickerProps.filter = filter;
      }
    });

    function changeIconPosition() {
      if (
        mappingProps.dateType === 'date' ||
        mappingProps.dateType === 'time' ||
        mappingProps.dateType === 'datetime'
      ) {
        const prefixInners = document.querySelectorAll(
          '.tr-datatimepicker .el-input__prefix-inner',
        );
        const suffixInners = document.querySelectorAll(
          '.tr-datatimepicker .el-input__suffix-inner',
        );

        // 遍历所有前缀和后缀元素
        prefixInners.forEach((prefixInner, index) => {
          const suffixInner = suffixInners[index];
          if (suffixInner) {
            // 将前缀元素移动到后缀元素后面
            suffixInner.parentNode.insertBefore(
              prefixInner,
              suffixInner.nextSibling,
            );
            // 设置前缀元素的样式
            prefixInner.classList.add('hack-icon');
            prefixInner.classList.add('div-icon-position');
            prefixInner.style.marginRight = '0px';
            prefixInner.style.marginLeft = '8px';
            prefixInner.style.color = 'rgba(0,0,0,.56)';
          }
        });
      }
      if (
        mappingProps.dateType === 'daterange' ||
        mappingProps.dateType === 'datetimerange'
      ) {
        const prefixInners = document.querySelectorAll(
          '.tr-datatimepicker .el-range__icon',
        );
        const suffixInners = document.querySelectorAll(
          '.tr-datatimepicker .el-range__close-icon',
        );
        prefixInners.forEach((prefixInner, index) => {
          const suffixInner = suffixInners[index];
          if (suffixInner) {
            // 将前缀元素移动到后缀元素后面
            suffixInner.parentNode.insertBefore(
              prefixInner,
              suffixInner.nextSibling,
            );
            // 设置前缀元素的样式
            prefixInner.classList.add('div-icon-position');
            prefixInner.style.marginRight = '0px';
            prefixInner.style.marginLeft = '8px';
            prefixInner.style.color = 'rgba(0,0,0,.56)';
          }
        });
      }
      const elements = document.querySelectorAll('.div-icon-position');
      elements.forEach(function (element) {
        element.addEventListener('click', function () {
          emit('focus');
        });
      });
    }
    //日期范围检查
    function checkDate(dateStr) {
      const date = dayjs(dateStr);
      // 根据提供的 mappingProps 解析最小和最大日期
      const minDate = dayjs(
        mappingProps.minDate ? mappingProps.minDate : '',
        'YYYY/MM/DD',
      );
      const maxDate = dayjs(
        mappingProps.maxDate ? mappingProps.maxDate : '',
        'YYYY/MM/DD',
      );

      if (minDate.isValid()) {
        if (!maxDate.isValid() || !minDate.isSameOrBefore(maxDate)) {
          // 如果 maxDate 无效或 minDate 不早于 maxDate，则仅检查 date 是否大于 minDate
          return date.isSameOrAfter(minDate);
        } else {
          // 如果 minDate 和 maxDate 都有效且 minDate 早于 maxDate，则检查 date 是否在范围内
          return date.isBetween(minDate, maxDate, null, '[]');
        }
      } else if (maxDate.isValid()) {
        // 如果 minDate 无效而 maxDate 有效，则仅检查 date 是否小于 maxDate
        return date.isSameOrBefore(maxDate);
      }
      return true;
    }

    //确定保存日期
    function saveDateTime(val) {
      let data = dateTime.value;

      if (data === 'Invalid Date') {
        dateTime.value = '';
      }
      if (typeof data === 'undefined') {
        data = '';
      }
      if (mappingProps.required) {
        divValidata();
      }
      // 日期时间类型选择时间会绕过范围
      if (
        mappingProps.dateType === 'datetime' &&
        mappingProps.maxDate &&
        mappingProps.minDate
      ) {
        let res = disabledDate(val);
        if (res) {
          dateTime.value = '';
          inputDateTime.value = '';
          return;
        }
      }
      let inputDate = data;
      // 输入框
      if (
        data &&
        typeof data === 'object' &&
        (mappingProps.dateType === 'daterange' ||
          mappingProps.dateType === 'datetimerange')
      ) {
        inputDate = [
          dayjs(data[0]).format(dateTimeFormat),
          dayjs(data[1]).format(dateTimeFormat),
        ];

        inputDateTime.value = inputDate;
      } else {
        if (!dayjs(inputDate).isValid()) {
          inputDateTime.value = '';
        }
        if (typeof inputDate === 'string') {
          inputDateTime.value = inputDate ? inputDate : '';
        }
      }
      // 组件值
      let postData = '';
      if (mappingProps.dateType.indexOf('range') > -1 && data) {
        postData = [
          dayjs(data[0]).format(dateTimeFormat),
          dayjs(data[1]).format(dateTimeFormat),
        ];
      } else {
        if (typeof data === 'object') {
          postData = data ? parseDateTime(data) : null;
          if (mappingProps.dateType == 'date' && mappingProps.dateWithTime) {
            postData = postData + ' 23:59:59';
          }
        } else {
          if (
            mappingProps.dateType === 'time' ||
            mappingProps.dateType === 'timeselect'
          ) {
            data = data ? data : '';
          }
          if (mappingProps.dateType == 'date' && mappingProps.dateWithTime) {
            data = data + ' 23:59:59';
          }
          postData = data ? data : null;
        }
      }

      // 快捷选择
      if (val && typeof val === 'string' && val.indexOf('@') > -1) {
        inputDateTime.value = val;
        postData = val;
      }
      // 设计时时间选择兼容
      if (mappingProps.dateType == 'time' && !!window['fas']?.inDesign) {
        postData = val;
      }

      //保存时更新父级绑定值
      emit('update:modelValue', postData ? postData : '');
      nextTick(() => {
        // 触发change事件
        valueUpdate(postData);
      });
    }

    function tmConfirm(time) {
      let data = time ?? tmDateTime.value;
      if (
        mappingProps.dateType === 'datetimerange' ||
        mappingProps.dateType === 'daterange'
      ) {
        let startTime = convertChineseDate(dayjs(data[0]).format(dateTimeFormat));
        let endTime = convertChineseDate(dayjs(data[1]).format(dateTimeFormat));
        dateTime.value = [startTime, endTime];
        inputDateTime.value = startTime + '-' + endTime;
        emit('update:modelValue', data ? [startTime, endTime] : '');
        nextTick(() => {
          valueUpdate(data ? [startTime, endTime] : '');
        });
      } else {
        let formatData = convertChineseDate(data);
        dateTime.value = formatData;
        let format = null;
        inputDateTime.value = formatData ? calDateTime(formatData, format) : '';
        let value =
          mappingProps.dateType === 'datetime'
            ? dayjs(formatData).format(dateTimeFormat)
            : mappingProps.dateType === 'date'
              ? dayjs(formatData.split(' ')[0]).format(dateTimeFormat)
              : formatData.indexOf(' ')>-1?formatData.split(' ')[1]:formatData;

        emit('update:modelValue', value ? value : '');
        nextTick(() => {
          valueUpdate(value ? value : '');
        });
      }
    }
    //日期时间格式化
    function calDateTime(data, format) {
      let isValidTime = true;

      if (
        mappingProps.dateType === 'time' ||
        mappingProps.dateType === 'timeselect'
      ) {
        isValidTime = dayjs(
          data?.indexOf(' ') > -1
            ? data
            : dayjs(new Date()).format('YYYY-MM-DD') + ' ' + data
        ).isValid();
      }

      return (
        dayjs(
          (mappingProps.dateType === 'time' ||
            mappingProps.dateType === 'timeselect') &&
            isValidTime
            ? data?.indexOf(' ') === -1
              ? dayjs(new Date()).format('YYYY-MM-DD') + ' ' + data
              : data
            : data,
        ).format(format ?? dateTimeFormat) ?? ''
      );
    }
    //日期时间反格式化
    function parseDateTime(data, format) {
      let formatData = dayjs(data).format(format ?? dateTimeFormat);
      if (
        mappingProps.dateType === 'time' ||
        mappingProps.dateType === 'timeselect'
      ) {
        formatData = dayjs(new Date()).format('YYYY-MM-DD') + ' ' + formatData;
      }
      return formatData;
    }
    // 中文时间转换为标准时间
    function convertChineseDate(dateStr) {
      if (!dateStr) return dateStr;

      // 处理中文上午/下午
      if (
        dateStr.includes('上午') ||
        dateStr.includes('下午')
      ) {
        const [datePart, timePart] = dateStr.split(/上午|下午/);

        const period = dateStr.includes('上午') ? 'AM' : 'PM';

        let [hours, minutes, seconds] = timePart.split(':').map(Number);

        // 转换为24小时制
        if (period === 'PM' && hours < 12) hours += 12;
        if (period === 'AM' && hours === 12) hours = 0;

        // 格式化时间部分
        const formattedTime = [
          hours.toString().padStart(2, '0'),
          minutes.toString().padStart(2, '0'),
          seconds.toString().padStart(2, '0'),
        ].join(':');

        // 返回标准格式
        return `${datePart.trim()} ${formattedTime}`;
      }

      return dateStr;
    }

    let inputFocus = false;
    function inputKeyDown() {
      if (inputFocus && event && event.key === 'Enter') {
        event.preventDefault(); // 阻止默认行为
        if (mappingProps.readonly || mappingProps.disable) {
          return;
        }
        if (mobileScreen.value) {
          showTmPicker();
        }
      }
    }
    function focusShow(evt) {
      inputFocus = true;
    }

    let stopEmit = false;
    function showTmPicker() {
      if (mobileScreen.value) {
        let time =
          mappingProps.dateType == 'time' ||
          mappingProps.dateType == 'timeselect'
            ? dayjs(
                dayjs(new Date()).format('YYYY-MM-DD') +
                  ' ' +
                  mappingProps.modelValue,
              ).format(dateTimeFormat)
            : dayjs(mappingProps.modelValue).isValid()
              ? dayjs(mappingProps.modelValue).format(dateTimeFormat)
              : '';
        if (
          mappingProps.dateType == 'datetimerange' ||
          mappingProps.dateType == 'daterange'
        ) {
          const today = new Date();
          const tomorrow = new Date(today);
          tomorrow.setDate(today.getDate() + 1);
          tomorrow.setHours(23, 59, 59);
          time =
            mappingProps.modelValue && Array.isArray(mappingProps.modelValue)
              ? [
                  mappingProps.modelValue[0]
                    ? new Date(mappingProps.modelValue[0])
                    : today,
                  mappingProps.modelValue[1]
                    ? new Date(mappingProps.modelValue[1])
                    : tomorrow,
                ]
              : [today, tomorrow];
        }
        tmDateTime.value = time ? time : new Date();
        refPicker.value.trigger();
      }
    }

    //onBlur
    function formatValue() {
      inputFocus = false;
      if (inputDateTime.value && inputDateTime.value !== 'Invalid Date') {
        let isValid =
          inputCheck(inputDateTime.value) && rangeCheck(inputDateTime.value);
        if (isValid) {
          let input = parseDateTime(inputDateTime.value);
          dateTime.value = calDateTime(
            input,
            mappingProps.dateType == 'time'
              ? 'HH:mm:ss'
              : mappingProps.dateType == 'datetime'
                ? 'YYYY/MM/DD HH:mm:ss'
                : 'YYYY/MM/DD',
          );
          inputDateTime.value = calDateTime(input);
          if (stopEmit) {
            //点击图标打开时间选择时会自动触发一次focus和blur，阻止这种行为带来的数据变化通知
            stopEmit = false;
            return;
          }
          emit('update:modelValue', dateTime.value ? dateTime.value : '');
        }
      } else {
        emit('update:modelValue', '');
      }
    }
    //时间格式校验
    function inputCheck(val) {
      if (val) {
        let isValid = dayjs(val).isValid();
        let isValidFormat = dayjs(val, dateTimeFormat, true).isValid();
        return isValid || isValidFormat;
      } else {
        return true;
      }
    }
    //时间范围校验
    function rangeCheck(val) {
      if (
        (!mappingProps.minDate && !mappingProps.maxDate) ||
        mappingProps.dateType === 'time' ||
        !val
      ) {
        return true;
      }
      const isValid = inputCheck(val);
      if (!isValid) {
        return false;
      }
      const parseDate = parseDateTime(val);
      const date = dayjs(parseDate).format('YYYY/MM/DD');
      let result = checkDate(date);
      return result;
    }
    function clearFunction(value) {
      emit('update:modelValue', '');
    }
    function valueUpdate(value) {
      emit('change', value);
    }
    // element-plus事件
    function emitBlur(e) {
      divValidata();
      emit('blur', e);
    }
    function emitFocus(e) {
      emit('focus', e);
    }
    function emitClear() {
      emit('clear');
    }
    function panelValueUpdate(val) {
      let date = val;
      emit('calendarChange', date);
    }
    function clickFunction() {
      if (mobileScreen.value) {
        if (mappingProps.readonly || mappingProps.disable) {
          return;
        }
        showTmPicker();
        refInput.value.blur();
      }
    }
    let labelPosition = computed(() => {
      if ($q.platform.is.mobile) {
        return 'top';
      }
      return mappingProps.labelPosition;
    });
    const disabledDate = date => {
      return !checkDate(date);
    };
    const validataResult = ref(true);
    // 自定义校验方法
    const divValidata = () => {
      if (mappingProps.rules && mappingProps.rules.length > 0) {
        validataResult.value = mappingProps.rules[0](dateTime.value);
        return validataResult.value === true;
      } else {
        return true;
      }
    };
    const elDatePickerOptions = computed(() => {
      return mappingProps.elDatePickerOptions;
    });

    const visibleChange = val => {
      const elements = document.querySelectorAll(
        '.el-picker__popper.tr-date-time-picker',
      );
      const visibleElement =
        Array.from(elements).find(
          el => window.getComputedStyle(el).display !== 'none',
        ) || null;
      if (!visibleElement) return;
      const shortcutsBtn = visibleElement.querySelectorAll(
        '.el-picker-panel__sidebar button',
      );
      if (
        val &&
        mappingProps.elDatePickerOptions.shortcuts &&
        mappingProps.modelValue &&
        mappingProps.modelValue.indexOf('@') > -1
      ) {
        nextTick(() => {
          let dayValue = mappingProps.modelValue;
          const targetButton = Array.from(shortcutsBtn).find(
            btn => btn.textContent.trim() === dayValue,
          );
          if (targetButton) {
            targetButton.style.color = 'var(--t-color)';
          }
        });
      } else {
        Array.from(shortcutsBtn).forEach(btn => {
          btn.style.color = '';
        });
      }
      emit('visibleChange', val);
    };

    return () => {
      return (
        <div
          class={['no-outline', 'under-trdate']}
          v-show={mappingProps.visible}
        >
          <TmDateTimePicker
            ref={refPicker}
            {...pickOwnForBasicComponent(
              mappingProps.tmRef,
              TmDateTimePicker.props,
              attrs,
            )}
            dateColumnsType={mappingProps.dateColumnsType}
            timeColumnsType={mappingProps.timeColumnsType}
            hideLabel={true}
            hideCell={true}
            dateType={
              mappingProps.dateType == 'timeselect'
                ? 'time'
                : mappingProps.dateType == 'datetimerange'
                  ? 'datetime'
                  : mappingProps.dateType
            }
            v-model={tmDateTime.value}
            calendarProps={
              mappingProps.dateType == 'datetimerange' ||
              mappingProps.dateType == 'daterange'
                ? { type: 'range' }
                : {}
            }
            confirmButtonText={
              mappingProps.confirmButtonText
                ? mappingProps.confirmButtonText
                : $q.lang.dateTime?.confirm
            }
            cancelButtonText={
              mappingProps.cancelButtonText
                ? mappingProps.cancelButtonText
                : $q.lang.dateTime?.cancel
            }
            onUpdate:modelValue={tmConfirm}
            onSelect={data => panelValueUpdate(data)}
            minDate={mobileMinDate.value}
            maxDate={mobileMaxDate.value}
          ></TmDateTimePicker>
          {mobileScreen.value ? (
            <Input
              labelPosition='left'
              ref={refInput}
              class={[
                'tr-date-time',
                'tr-input-form',
                styles.module,
                'no-outline',
              ]}
              {...pickOwnForBasicComponent(mappingProps, Input.props, attrs)}
              required={mappingProps.required}
              placeholder={mappingProps.placeholder}
              debounce={300}
              v-model={inputDateTime.value}
              clearable={true}
              clear-icon='cancel'
              rules={mappingProps.rules}
              lazy-rules={true}
              onClick={clickFunction}
              onClear={clearFunction}
              onBlur={e => emitBlur(e)}
              onFocus={e => emitFocus(e)}
            >
              {{
                append: () => {
                  return (
                    <Icon
                      name={
                        mappingProps.dateType == 'time'
                          ? 'access_time'
                          : 'event'
                      }
                      class='cursor-pointer no-outline'
                      v-show={!mappingProps.disable && !mappingProps.readonly}
                      tabIndex='-1'
                      onClick={showTmPicker}
                    />
                  );
                },
              }}
            </Input>
          ) : (
            <LabelPrefixWraper
              style={
                labelPosition.value == 'top'
                  ? 'gap:4px'
                  : validataResult.value !== true
                    ? 'align-items:baseline'
                    : ''
              }
              required={mappingProps.required}
              label={mappingProps.label}
              hideLabel={mappingProps.hideLabel}
              labelType='input'
              labelPosition={labelPosition.value}
              helpConf={mappingProps.helpConf}
              readonly={mappingProps.readonly}
              helpTooltip={mappingProps.helpTooltip}
              helpPlacement={mappingProps.helpPlacement}
              helpMore={mappingProps.helpMore}
              maxHeight={mappingProps.maxHeight}
              maxWidth={mappingProps.maxWidth}
              helpMorePopup={mappingProps.helpMorePopup}
              helpMoreLink={mappingProps.helpMoreLink}
              helpMoreLinkHrefStatic={mappingProps.helpMoreLinkHrefStatic}
              helpMoreLinkHrefExp={mappingProps.helpMoreLinkHrefExp}
            >
              <div
                class={[
                  'date-time-section',
                  labelPosition.value == 'top' && 'date-time-section-top',
                  mobileScreen.value && 'isMobile',
                  mappingProps.readonly && 'is-readonly',
                ]}
              >
                <ElConfigProvider
                  locale={language[getUserLanguage() ?? $q?.lang.getLocale()]}
                >
                  {mappingProps.dateType == 'datetime' ||
                  mappingProps.dateType == 'date' ||
                  mappingProps.dateType == 'daterange' ||
                  mappingProps.dateType == 'datetimerange' ? (
                    <div>
                      <ElDatePicker
                        {...pickOwnForBasicComponent(
                          mappingProps.elDatePickerOptions,
                          ElDatePicker.props,
                          attrs,
                        )}
                        unlink-panels={
                          elDatePickerOptions.value?.unlinkPanels ?? false
                        }
                        default-value={
                          elDatePickerOptions.value?.defaultValue ??
                          (mappingProps.dateType.indexOf('range') > -1
                            ? [
                                new Date(
                                  new Date().getFullYear(),
                                  new Date().getMonth(),
                                  1,
                                ),
                                new Date(
                                  new Date().getFullYear(),
                                  new Date().getMonth() + 1,
                                  1,
                                ),
                              ]
                            : undefined)
                        }
                        default-time={
                          elDatePickerOptions.value.defaultTime ??
                          (mappingProps.dateType.indexOf('range') > -1
                            ? [
                                new Date(2000, 1, 1, 0, 0, 0),
                                new Date(2000, 2, 1, 23, 59, 59),
                              ]
                            : defaultTimeMap[
                                mappingProps.defaultTimeForDateTime
                              ])
                        }
                        format={mappingProps.format ?? dateTimeFormat}
                        value-format={
                          mappingProps.valueFormat ?? dateTimeFormat
                        }
                        ref={refDate}
                        v-model={dateTime.value}
                        class={[
                          'tr-datatimepicker',
                          validataResult.value !== true
                            ? 'div-error-input'
                            : '',
                        ]}
                        prefix-icon=''
                        range-separator={$q.lang.dateTime?.to || '-'}
                        type={mappingProps.dateType}
                        onChange={data => saveDateTime(data)}
                        onCalendarChange={data => panelValueUpdate(data)}
                        onBlur={e => emitBlur(e)}
                        onFocus={e => emitFocus(e)}
                        onClear={emitClear}
                        disabled-date={disabledDate}
                        popper-class='tr-date-time-picker'
                        placement={
                          elDatePickerOptions.value?.placement
                            ? elDatePickerOptions.value?.placement
                            : mappingProps.dateType.indexOf('range') > -1
                              ? 'bottom'
                              : 'bottom-end'
                        }
                        fallbackPlacements={
                          elDatePickerOptions.value?.fallbackPlacements
                            ? elDatePickerOptions.value?.fallbackPlacements
                            : [
                                'auto',
                                'top',
                                'top-end',
                                'bottom',
                                'bottom-start',
                                'bottom-end',
                                'right',
                                'left',
                              ]
                        }
                        placeholder={mappingProps.placeholder}
                        readonly={mappingProps.readonly}
                        disabled={mappingProps.disable}
                        tabIndex={attrs.tabIndex ?? 1}
                        onVisibleChange={val => visibleChange(val)}
                        // v-slots={{
                        //   'prev-month': () => (
                        //     <i class="el-icon">
                        //       <arrowLeftIcon />
                        //     </i>
                        //   ),
                        //   'next-month': () => (
                        //     <i class="el-icon">
                        //       <arrowRightIcon />
                        //     </i>
                        //   ),
                        // }}
                      />

                      <div
                        v-show={validataResult.value !== true}
                        class='div-error-label'
                      >
                        {validataResult.value}
                      </div>
                    </div>
                  ) : mappingProps.dateType == 'time' ||
                    mappingProps.dateType == 'timerange' ? (
                    <div>
                      <ElTimePicker
                        {...pickOwnForBasicComponent(
                          mappingProps.elTimePickerOptions,
                          ElTimePicker.props,
                          attrs,
                        )}
                        is-range={
                          mappingProps.dateType == 'timerange' || undefined
                        }
                        ref={refTime}
                        format={mappingProps.format ?? dateTimeFormat}
                        value-format={
                          mappingProps.valueFormat ?? dateTimeFormat
                        }
                        v-model={dateTime.value}
                        class={[
                          'tr-datatimepicker tr-datatimepicker-time',
                          validataResult.value !== true
                            ? 'div-error-input'
                            : '',
                        ]}
                        popper-class='tr-date-time-picker'
                        placement={'bottom-end'}
                        placeholder={mappingProps.placeholder}
                        readonly={mappingProps.readonly}
                        disabled={mappingProps.disable}
                        onChange={data => saveDateTime(data)}
                        onBlur={e => emitBlur(e)}
                        onFocus={e => emitFocus(e)}
                        onClear={emitClear}
                        tabIndex={attrs.tabIndex ?? 1}
                        onVisibleChange={val => visibleChange(val)}
                      />

                      <div
                        v-show={validataResult.value !== true}
                        class='div-error-label'
                      >
                        {validataResult.value}
                      </div>
                    </div>
                  ) : mappingProps.dateType == 'timeselect' ? (
                    <div>
                      <ElTimeSelect
                        {...pickOwnForBasicComponent(
                          mappingProps.elTimeSelectOptions,
                          ElTimeSelect.props,
                          attrs,
                        )}
                        ref={refTimeSelect}
                        prefix-icon=''
                        v-model={dateTime.value}
                        class={[
                          'tr-datatimepicker',
                          'tr-datatimepicker-timeselect',
                          validataResult.value !== true
                            ? 'div-error-input'
                            : '',
                        ]}
                        format='HH:mm'
                        popper-class='tr-date-time-picker'
                        placeholder={mappingProps.placeholder}
                        readonly={mappingProps.readonly}
                        disabled={mappingProps.disable}
                        onChange={saveDateTime}
                        onBlur={e => emitBlur(e)}
                        onFocus={e => emitFocus(e)}
                        tabIndex={attrs.tabIndex ?? 1}
                        start={mappingProps.start}
                        end={mappingProps.end}
                        step={mappingProps.step}
                        suffix-icon={arrowDownIcon}
                        onVisibleChange={val => visibleChange(val)}
                      />

                      <div
                        v-show={validataResult.value !== true}
                        class='div-error-label'
                      >
                        {validataResult.value}
                      </div>
                    </div>
                  ) : (
                    ''
                  )}
                </ElConfigProvider>
              </div>
            </LabelPrefixWraper>
          )}
        </div>
      );
    };
  },
});
